/**
 * 求 SIGMA{SGIMA{lcm(i, j)}}
 * 经过反演，原式变为：
 * SIGMA{x * SIGMA{i*mu(i), i|x} * SGIMA{u} * SIGMA{v}}
 * 令 F(x) = SIGMA{i*mu(i), i|x}
 * 这是一个积性函数，可以线性筛出所有的值，然后可以在O(N)时间解出。
 * 对于多case情况，可以使用整除分块，在sqrt(N)时间解出每个case
 */
#include <bits/stdc++.h>
using namespace std;

namespace OY {
    template <uint64_t P, bool IsPrime, typename = typename std::enable_if<(P > 1 && P < uint64_t(1) << 63)>::type>
    struct StaticModInt64 {
        using mint = StaticModInt64<P, IsPrime>;
        using mod_type = uint64_t;
        mod_type m_val;
        static mod_type _mul(mod_type a, mod_type b) {
#ifdef _MSC_VER
            mod_type high, low, res;
            low = _umul128(a, b, &high);
            _udiv128(high, low, mod(), &res);
            return res;
#else
            int64_t res = a * b - mod_type((long double)(a)*b / mod()) * mod();
            if (res < 0)
                res += mod();
            else if (res >= mod())
                res -= mod();
            return res;
#endif
        }
        StaticModInt64() = default;
        template <typename Tp, typename std::enable_if<std::is_signed<Tp>::value>::type * = nullptr>
        StaticModInt64(Tp val) : m_val{} {
            auto x = val % int64_t(mod());
            if (x < 0) x += mod();
            m_val = x;
        }
        template <typename Tp, typename std::enable_if<std::is_unsigned<Tp>::value>::type * = nullptr>
        StaticModInt64(Tp val) : m_val(val % mod()) {}
        static mint raw(mod_type val) {
            mint res;
            res.m_val = val;
            return res;
        }
        static constexpr mod_type mod() { return P; }
        mod_type val() const { return m_val; }
        mint pow(uint64_t n) const {
            mod_type res = 1, b = m_val;
            while (n) {
                if (n & 1) res = _mul(res, b);
                b = _mul(b, b), n >>= 1;
            }
            return raw(res);
        }
        mint inv() const {
            if (IsPrime)
                return inv_Fermat();
            else
                return inv_exgcd();
        }
        mint inv_exgcd() const {
            mod_type x = mod(), y = m_val, m0 = 0, m1 = 1;
            while (y) {
                mod_type z = x / y;
                x -= y * z, m0 -= m1 * z, std::swap(x, y), std::swap(m0, m1);
            }
            if (m0 >= mod()) m0 += mod() / x;
            return raw(m0);
        }
        mint inv_Fermat() const { return pow(mod() - 2); }
        mint &operator++() {
            if (++m_val == mod()) m_val = 0;
            return *this;
        }
        mint &operator--() {
            if (!m_val) m_val = mod();
            m_val--;
            return *this;
        }
        mint operator++(int) {
            mint old(*this);
            ++*this;
            return old;
        }
        mint operator--(int) {
            mint old(*this);
            --*this;
            return old;
        }
        mint &operator+=(const mint &rhs) {
            m_val += rhs.m_val;
            if (m_val >= mod()) m_val -= mod();
            return *this;
        }
        mint &operator-=(const mint &rhs) {
            m_val += mod() - rhs.m_val;
            if (m_val >= mod()) m_val -= mod();
            return *this;
        }
        mint &operator*=(const mint &rhs) {
            m_val = _mul(m_val, rhs.m_val);
            return *this;
        }
        mint &operator/=(const mint &rhs) { return *this *= rhs.inv(); }
        mint operator+() const { return *this; }
        mint operator-() const { return raw(m_val ? mod() - m_val : 0); }
        bool operator==(const mint &rhs) const { return m_val == rhs.m_val; }
        bool operator!=(const mint &rhs) const { return m_val != rhs.m_val; }
        bool operator<(const mint &rhs) const { return m_val < rhs.m_val; }
        bool operator>(const mint &rhs) const { return m_val > rhs.m_val; }
        bool operator<=(const mint &rhs) const { return m_val <= rhs.m_val; }
        bool operator>=(const mint &rhs) const { return m_val <= rhs.m_val; }
        template <typename Tp>
        explicit operator Tp() const { return Tp(m_val); }
        friend mint operator+(const mint &a, const mint &b) { return mint(a) += b; }
        friend mint operator-(const mint &a, const mint &b) { return mint(a) -= b; }
        friend mint operator*(const mint &a, const mint &b) { return mint(a) *= b; }
        friend mint operator/(const mint &a, const mint &b) { return mint(a) /= b; }
    };
    template <typename Istream, uint64_t P, bool IsPrime>
    Istream &operator>>(Istream &is, StaticModInt64<P, IsPrime> &x) { return is >> x.m_val; }
    template <typename Ostream, uint64_t P, bool IsPrime>
    Ostream &operator<<(Ostream &os, const StaticModInt64<P, IsPrime> &x) { return os << x.val(); }
    using mint4611686018427387847 = StaticModInt64<4611686018427387847, true>;
    using mint9223372036854775783 = StaticModInt64<9223372036854775783, true>;
}

using llt = long long;
using mint = OY::StaticModInt64<20101009, true>;
int const SZ = 10000001;


struct Sieve{ // 线性筛法

using llt = int;
vector<bool> isComp; // isComp[i]表示i是否为合数
vector<llt> primes; // primes[i]是第i个质数
vector<mint> Fx;    // F(x) = SIGMA{ixmu(i),i|x}

Sieve(int SZ = 35000){
    primes.reserve(SZ);
    isComp.assign(SZ, false);    

    Fx.assign(SZ, 0);
    Fx[1] = 1;
 
    long long tmp;
    for(int i=2;i<SZ;++i){
        if(!isComp[i]){
            primes.push_back(i);
            Fx[i] = mint(1 - i);
        }

        for(int j=0,n=primes.size();j<n&&(tmp=i*(long long)primes[j])<SZ;++j){
            isComp[tmp] = true;

            if(0 == i % primes[j]){
                Fx[tmp] = Fx[i];
                break;
            }else{
                Fx[tmp] = Fx[i] * Fx[primes[j]];
            }
        }
    }
}

}Sie(SZ);

vector<mint> Sum;

void init(){
    Sum.assign(SZ, 0);
    for(int i=1;i<SZ;++i){
        Sum[i] = Sum[i - 1] + mint(i) * Sie.Fx[i];
    }    
    return;
}

llt N, M;

void work(){
    cin >> N >> M;
    if(N > M) swap(N, M);
    mint ans = 0;
    for(int j,i=1;i<=N;i=j+1){
        llt x = N / i, y = M / i;
        j = min(N/x, M/y);
        x = x * (x + 1) / 2;
        y = y * (y + 1) / 2;
        ans += (Sum[j] - Sum[i - 1]) * x * y;
    }
    cout << ans << endl;
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("z.txt", "r", stdin);
#endif
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);	
    init();
    int nofkase = 1;
	// // cin >> nofkase;
	while(nofkase--) work();
	return 0;
}